/* 
 * Copyright (c) 2012 JSquirrelEngine
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in 
 * the Software without restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
 * Software, and to permit persons to whom the Software is furnished to do so, subject
 * to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 */

package org.jsquirrel.geometry;

import org.jsquirrel.math.F2Vector;


/**
 * Abstract class to define the basic behavior of a bounding area for a polygon.
 * 
 * @author Juan David Adarve Bermudez
 *
 */
public abstract class BoundingArea {
	
	//*********************************************************************************************
	// INSTANCE ATTRIBUTES
	//*********************************************************************************************
	
	/**
	 * Tells the type of this BoundingArea, it cannot be modified by any child class
	 */
	private BoundingAreaType type;
	
	
	//*********************************************************************************************
	// CONSTRUCTORS
	//*********************************************************************************************

	/**
	 * Constructor, establish the BoundingAreaType for this instance
	 */
	public BoundingArea(BoundingAreaType type) {
		this.type = type;
	}
	
		
	//*********************************************************************************************
	// PUBLIC METHODS
	//*********************************************************************************************
	
	public final BoundingAreaType type() {
		return type;
	}
	
	
	//*********************************************************************************************
	// PUBLIC ABSTRACT METHODS
	//*********************************************************************************************
	
	/**
	 * Checks intersection of this BoundingArea instance with another instance. In case the area parameter
	 * is null, the behavior of this method is undefined.
	 * 
	 * @param area BoundingArea instance.
	 * 
	 * @return true in case of intersection, false otherwise.
	 * 
	 * @throws UnsupportedBoundingIntersectionException in case the intersection check is not supported between the
	 * types of both instances.
	 * 
	 */
	public abstract boolean intersects(final BoundingArea area) throws UnsupportedBoundingIntersectionException;
	
	/**
	 * Checks intersection between this BoundingArea instance and the rectangle described by the positions of
	 * the bottom left corner and its width and height
	 * 
	 * @param xLeft X coordinate for the bottom left corner
	 * @param yLeft Y coordinate for the bottom left corner
	 * @param width rectangle width
	 * @param height rectangle height
	 * 
	 * @return true in case of intersection, false otherwise
	 * 
	 * @throws UnsupportedBoundingIntersectionException in case the intersection checking is not supported by this
	 * BoundingArea implementation
	 */
	public abstract boolean intersectsRectangle(float xLeft, float yLeft, float width, float height) throws UnsupportedBoundingIntersectionException;
	
	/**
	 * Calculates the bounding rectangle, described as the bottom left and upper right corners, for this BoundingArea
	 * implementation. In case any parameter is null, the behavior of this method is undefined.
	 * 
	 * @param bLeftCorner (output) vector on which the bottom left corner is stored.
	 * @param uRightCorner (output) vector on which the upper right corner is stored.
	 */
	public abstract void getBoundingRectangle(F2Vector bLeftCorner, F2Vector uRightCorner);
	
	/**
	 * Updates the parameters of this BoundingArea so that the Polygon p is contained in the area of this BoundingArea
	 * implementation. In case p is null, the behavior of this method is undefined 
	 * 
	 * @param p Polygon used to update this BoundingArea
	 */
	public abstract void update(final Polygon p);
}
